import { app, BrowserWindow, ipcMain, screen, Menu, dialog, shell, nativeImage } from 'electron'
import path from 'path'
import net from 'net'
import { exec } from 'child_process'
import fs from 'fs'
import { ExifImage } from 'exif';

function getConfigPath() {
  return path.join(process.cwd(), 'config.json')
}

function loadConfig() {
  const configPath = getConfigPath()
  try {
    const rawData = fs.readFileSync(configPath, 'utf-8')
    return JSON.parse(rawData)
  } catch (error) {
    console.error('加载配置失败，使用默认值', error)
    return {
      OCR_PATH: 'E:\\Umi-OCR_Paddle_v2.1.5\\Umi-OCR.exe', // 默认值
      OCR_PORT: 1224
    }
  }
}

// 使用配置
const { OCR_PATH, OCR_PORT } = loadConfig()
// const OCR_PATH = 'E:\\Umi-OCR_Paddle_v2.1.5\\Umi-OCR.exe'
// const OCR_PORT = 1224

let mainWindow: BrowserWindow | null = null

// 检查OCR服务是否可用
function isOCRRunning(): Promise<boolean> {
  return new Promise((resolve) => {
    const socket = net.createConnection(OCR_PORT, '127.0.0.1', () => {
      socket.end()
      resolve(true)
    })
    socket.on('error', () => resolve(false))
  })
}

// 启动OCR软件
async function startOCR(): Promise<void> {
  return new Promise((resolve, reject) => {
    const { shell } = require('electron')
    console.log('OCR_PATH', OCR_PATH)
    shell.openPath(OCR_PATH)
      .then((error: string) => {
        if (error) {
          return reject(new Error(error))
        }
        const checkInterval = setInterval(async () => {
          if (await isOCRRunning()) {
            clearInterval(checkInterval)
            resolve()
          }
        }, 1000)
      })
      .catch(reject)
  })
}

// 调用OCR API
interface OCROptions {
  'ocr.language'?: string
  'ocr.cls'?: boolean
  'ocr.limit_side_len'?: string
  'tbpu.parser'?: string
  'data.format'?: string
}

interface OCRResult {
  data: {
    text: string
    end: string
  }[]
}

async function callOCRApi(imageData: string, options?: OCROptions): Promise<OCRResult> {
  const cleanBase64 = imageData.replace(/^data:image\/\w+;base64,/, '')

  const data = {
    base64: cleanBase64,
    options: {
      'ocr.language': 'models/config_chinese.txt',
      'ocr.cls': true,
      'ocr.limit_side_len': '999999',
      'tbpu.parser': 'none',
      'data.format': 'dict',
      ...options
    }
  }

  try {
    const response = await fetch(`http://127.0.0.1:${OCR_PORT}/api/ocr`, {
      method: 'POST',
      body: JSON.stringify(data),
      headers: {
        'Content-Type': 'application/json'
      }
    })

    if (!response.ok) {
      let errorDetail = response.statusText
      try {
        const errorResponse = await response.json()
        if (errorResponse.message) {
          errorDetail = errorResponse.message
        }
      } catch (e) { }
      throw new Error(`OCR请求失败: ${response.status} - ${errorDetail}`)
    }

    return await response.json()
  } catch (error) {
    throw new Error(`OCR请求过程中出错: ${(error as Error).message}`)
  }
}

function createWindow(): void {
  const primaryDisplay = screen.getPrimaryDisplay()
  const { width, height } = primaryDisplay.workAreaSize

  mainWindow = new BrowserWindow({
    minWidth: 800,
    minHeight: 600,
    width: Math.floor(width),
    height: Math.floor(height),
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false,
      sandbox: false,
      webSecurity: false, // 开发环境允许跨域
    }
  })
  // 注册IPC处理器
  setupIPCHandlers();

  Menu.setApplicationMenu(null)

  if (import.meta.env.DEV) {
    mainWindow.loadURL(import.meta.env.VITE_DEV_SERVER_URL as string)
    mainWindow.webContents.openDevTools()
  } else {
    mainWindow.loadFile(path.join(__dirname, '../dist/index.html'))
  }

  app.on('ready', async () => {
    console.log('应用已准备就绪，检查OCR服务...')
    try {
      if (!await isOCRRunning()) {
        await startOCR()
        console.log('OCR启动成功')
      }
    } catch (err) {
      console.error('启动OCR失败:', err)
    }
  })
}

app.whenReady().then(createWindow)

ipcMain.handle('run-ocr', async (event, { imageData }: { imageData: any }) => {
  const data = imageData.imageData
  try {
    if (typeof data !== 'string' || !data.startsWith('data:image')) {
      throw new Error('无效的图片数据格式')
    }

    const result = await callOCRApi(data)
    return result
  } catch (error) {
    throw new Error(`OCR处理失败: ${(error as Error).message}`)
  }
})

ipcMain.handle('open-software', (event, path: string) => {
  return new Promise((resolve, reject) => {
    exec(path, (error, stdout, stderr) => {
      if (error) {
        reject({
          message: '执行失败',
          error: error.message,
          stderr
        })
      } else {
        resolve({
          message: '执行成功',
          stdout
        })
      }
    })
  })
})

ipcMain.handle('check-port-status', async (event, port: number) => {
  return new Promise((resolve) => {
    const socket = net.createConnection(port, '127.0.0.1', () => {
      socket.end()
      resolve(true)
    })

    socket.on('error', () => resolve(false))
    socket.setTimeout(2000, () => {
      socket.destroy()
      resolve(false)
    })
  })
})


// 类型定义
interface DirectoryEntry {
  name: string;
  path: string;
  type: 'directory' | 'file';
  children?: Array<FileEntry | DirectoryEntry>;
  size?: number;
  mtime?: string;
}

interface PhotoMetadata {
  fileName: string;
  filePath: string;
  dateTime: string;
  createDate: string;
  modifyDate: string;
  camera: string;
  lens: string;
  focalLength: string;
  exposure: string;
  aperture: string;
  iso: string;
  width: number;
  height: number;
  description: string;
  rawMetadata: any;
}

ipcMain.handle('open-file-dialog', async (event) => {
  const result = await dialog.showOpenDialog({
    properties: ['openFile'],
    // filters: [{ name: 'Images', extensions: ['jpg', 'jpeg', 'png', 'gif', 'tif', 'tiff', 'bmp'] }]
  })
  return result.filePaths[0] // 返回完整路径如 "C:\Users\name\Pictures\photo.jpg"
})

// 处理文件读取
ipcMain.handle('read-file', async (_, path) => {
  const fs = require('fs').promises
  return await fs.readFile(path)
})

// 格式化元数据
function formatMetadata(metadata: any, imagePath: string): PhotoMetadata {
  return {
    fileName: path.basename(imagePath),
    filePath: imagePath,
    dateTime: metadata.DateTimeOriginal || '',
    createDate: metadata.CreateDate || '',
    modifyDate: metadata.ModifyDate || '',
    camera: `${metadata.Make || ''} ${metadata.Model || ''}`.trim(),
    lens: metadata.LensModel || '',
    focalLength: metadata.FocalLength ? `${metadata.FocalLength}mm` : '',
    exposure: metadata.ExposureTime ? `${metadata.ExposureTime}s` : '',
    aperture: metadata.FNumber ? `f/${metadata.FNumber}` : '',
    iso: metadata.ISO || '',
    width: metadata.ImageWidth || 0,
    height: metadata.ImageHeight || 0,
    description: metadata.Description || metadata.ImageDescription || '',
    rawMetadata: metadata
  };
}

// 读取图片元数据
ipcMain.handle('get-image-metadata', async (event, imagePath: string) => {
  const result: any = await getImageMetadata(imagePath);
  if (!result) {
    console.error('读取图片元数据失败:', imagePath);
    return null;
  }
  return result
});

function getImageMetadata(filePath: string) {
  return new Promise((resolve) => {
    try {
      new ExifImage({ image: filePath }, (error, exifData) => {
        if (error) {
          console.warn('读取EXIF警告(可能图片无EXIF数据):', error.message);
          resolve({ 
            basicInfo: {
              path: filePath,
              hasExif: false,
              message: 'No EXIF data found'
            }
          });
        } else {
          resolve({
            ...exifData,
            basicInfo: {
              path: filePath,
              hasExif: true
            }
          });
        }
      });
    } catch (error: any) {
      console.error('处理图片时出错:', error);
      resolve({
        basicInfo: {
          path: filePath,
          hasExif: false,
          error: error.message
        }
      });
    }
  });
}


// =====================================
// 类型定义
interface FileEntry {
  name: string;
  path: string;
  type: 'file';
  size: number;
  mtime: string;
  ext: string;
}

interface DirectoryEntry {
  name: string;
  path: string;
  type: 'directory' | 'file';
  children?: Array<FileEntry | DirectoryEntry>;
}

type Entry = FileEntry | DirectoryEntry;

// 配置
const MAX_DEPTH = 10; // 最大递归深度
const SUPPORTED_EXTS = new Set([
  '.jpg', '.jpeg', '.png', '.gif', '.bmp',
  '.tif', '.tiff', '.webp', '.heic', '.heif'
]);

// 设置IPC通信
function setupIPCHandlers() {
  // 选择目录
  ipcMain.handle('select-directory', async () => {
    const { filePaths } = await dialog.showOpenDialog({
      properties: ['openDirectory'],
      title: '选择照片目录'
    });
    return filePaths[0] || null;
  });

  // 解析目录结构（带进度回调）
  ipcMain.handle('parse-directory', async (event, dirPath: string) => {
    return parseDirectoryRecursive(dirPath, (progress) => {
      event.sender.send('parse-progress', progress);
    });
  });
}

// 递归解析目录（核心实现）
async function parseDirectoryRecursive(
  dirPath: string,
  progressCallback?: (progress: { scanned: number; found: number }) => void,
  depth = 0
): Promise<DirectoryEntry> {
  if (depth > MAX_DEPTH) {
    console.warn(`达到最大递归深度: ${dirPath}`);
    return {
      name: path.basename(dirPath),
      path: dirPath,
      type: 'directory',
      children: []
    };
  }

  const entry: DirectoryEntry = {
    name: path.basename(dirPath),
    path: dirPath,
    type: 'directory',
    children: []
  };

  try {
    const items = await fs.promises.readdir(dirPath);
    let scanned = 0;
    let found = 0;

    for (const item of items) {
      try {
        const fullPath = path.join(dirPath, item);
        const stats = await fs.promises.stat(fullPath);

        if (stats.isDirectory()) {
          const subDir = await parseDirectoryRecursive(
            fullPath,
            progressCallback,
            depth + 1
          );
          if (!entry.children) entry.children = [];
          entry.children.push(subDir);
        } else if (stats.isFile()) {
          const ext = path.extname(item).toLowerCase();
          // if (SUPPORTED_EXTS.has(ext)) {
            if (!entry.children) entry.children = [];
            entry.children.push({
              name: item,
              path: fullPath,
              type: 'file',
              size: stats.size,
              mtime: stats.mtime.toISOString(),
              ext
            });
            found++;
          // }
        }

        scanned++;
        if (progressCallback && scanned % 10 === 0) {
          progressCallback({ scanned, found });
        }
      } catch (err) {
        console.error(`处理 ${item} 失败:`, err);
      }
    }
  } catch (err) {
    console.error(`读取目录 ${dirPath} 失败:`, err);
  }
  return entry;
}

ipcMain.handle('get-config', () => {
  return loadConfig();
});


app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

ipcMain.handle('open-file', async (event, filePath: string) => {
  try {
    await shell.openPath(filePath)
    console.log('文件已用默认程序打开:', filePath)
  } catch (error) {
    console.error('打开文件失败:', error, filePath)
    throw new Error(`打开文件失败: ${(error as Error).message}`)
  }
})

// 处理读取图片请求
ipcMain.handle('read-image', async (event, filePath: string) => {
  try {
    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      throw new Error('文件不存在')
    }

    // 读取图片文件
    const image = nativeImage.createFromPath(filePath)
    if (image.isEmpty()) {
      throw new Error('无法读取图片')
    }

    // 获取图片信息
    const size = image.getSize()
    const buffer = image.toPNG() // 转换为PNG格式的Buffer

    // 返回图片数据
    return {
      success: true,
      data: {
        buffer: buffer.toString('base64'), // 转换为base64
        width: size.width,
        height: size.height,
        path: filePath,
        mimeType: 'image/png'
      }
    }
  } catch (error) {
    console.error('读取图片失败:', error)
    return {
      success: false,
      error: error
    }
  }
})